package com.module.admin.app.utils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import com.module.admin.app.pojo.AppApiTestDtl;
import com.module.admin.app.pojo.AppApiTestLog;
import com.module.admin.app.service.AppApiTestLogService;
import com.module.admin.prj.pojo.PrjApi;
import com.module.admin.prj.pojo.PrjMonitor;
import com.module.admin.prj.service.PrjMonitorService;
import com.module.admin.sys.pojo.SysUser;
import com.system.comm.utils.FrameHttpUtil;
import com.system.comm.utils.FrameJsonUtil;
import com.system.comm.utils.FrameMapUtil;
import com.system.comm.utils.FrameStringUtil;
import com.system.comm.utils.FrameTimeUtil;
import com.system.handle.model.ResponseFrame;

@Component
public class ApiTestUtil {

	private static final Logger LOGGER = LoggerFactory.getLogger(ApiTestUtil.class);
	@Autowired
	private PrjMonitorService prjMonitorService;
	@Autowired
	private AppApiTestLogService appApiTestLogService;

	public ResponseFrame post(AppApiTestDtl test, PrjApi api, String batchNo, SysUser user) {
		ResponseFrame frame = new ResponseFrame();
		if (batchNo == null) {
			batchNo = FrameTimeUtil.getStrTime();
		}
		Map<String, Object> params = new HashMap<String, Object>();
		List<Map<String, Object>> paramList = FrameJsonUtil.toListMap(test.getParams());
		for (Map<String, Object> map : paramList) {
			String value = FrameMapUtil.getString(map, "value");
			if (value != null && value.startsWith("no") && value.contains("_")) {
				// 从之前的序号获取相应的内容作为参数传入
				List<String> valueList = FrameStringUtil.toArray(value, "_");
				String orderby = valueList.get(0);
				orderby = orderby.replaceAll("no", "");
				boolean isFindValue = false;
				AppApiTestLog noTestDtl = appApiTestLogService.getByAatIdOrderby(test.getAatId(), orderby);
				if (noTestDtl != null) {
					String resultPost = noTestDtl.getResult();
					if (resultPost.startsWith("{")) {
						Map<String, Object> postMap = FrameJsonUtil.toMap(resultPost);
						List<String> codeList = FrameStringUtil.toArray(valueList.get(1), "\\.");
						if (codeList.size() == 1) {
							value = FrameMapUtil.getString(postMap, codeList.get(0));
							isFindValue = true;
						} else if (codeList.size() == 2) {
							@SuppressWarnings("unchecked")
							Map<String, Object> dataMap = FrameMapUtil.getMap(postMap, codeList.get(0));
							value = FrameMapUtil.getString(dataMap, codeList.get(1));
							isFindValue = true;
						}
					}
				}
				if (!isFindValue) {
					value = null;
				}
			}
			params.put(FrameMapUtil.getString(map, "key"), value);
		}

		PrjMonitor monitor = prjMonitorService.getService(test.getPrjId());
		if(monitor == null) {
			AppApiTestLog appApiTestLog = new AppApiTestLog();
			// 批次[测试时间]
			appApiTestLog.setBatchNo(batchNo);
			appApiTestLog.setAatdId(test.getAatdId());
			appApiTestLog.setTestUserId(user.getUserId());
			appApiTestLog.setParams(FrameJsonUtil.toString(params));
			// 响应结果
			appApiTestLog.setResult("{}");
			// 正确结果
			appApiTestLog.setResultSucc(test.getSuccResult());
			// 状态[30成功、40失败]
			appApiTestLog.setStatus(40);
			// 状态消息
			appApiTestLog.setStatusMsg("服务没有启动");
			// 对比结果
			appApiTestLog.setResultComparison("服务没有启动");
			appApiTestLogService.save(appApiTestLog);
			return new ResponseFrame(-3, "服务没有启动");
		}
		String url = "http://" + monitor.getRemark() + test.getPath();
		String resultPost = post(api, url, params);
		// 判断返回结果
		Integer status = 30;
		String statusMsg = "通过";
		String resultComparison = "";
		if (resultPost.startsWith("{")) {
			Map<String, Object> postMap = FrameJsonUtil.toMap(resultPost);
			String result = test.getSuccResult();
			Map<String, Object> resultMap = FrameJsonUtil.toMap(result);
			Iterator<Entry<String, Object>> entryKeyIterator = resultMap.entrySet().iterator();
			// 处理正确的结果
			while (entryKeyIterator.hasNext()) {
				Entry<String, Object> e = entryKeyIterator.next();
				Object value = e.getValue();
				if (value instanceof String) {
					if ("variableValue".equals(value.toString())) {
						// 为变动的值，不做判断
						continue;
					}
					String postValue = FrameMapUtil.getString(postMap, e.getKey());
					if (postValue == null || !value.toString().equals(postValue)) {
						// 值不一致
						status = 40;
						statusMsg = "返回值不一致";
						resultComparison += e.getKey() + "的响应值" + postValue + "!=" + value.toString() + ";";
					}
				} else if (value instanceof Integer || value instanceof Double || value instanceof Float) {
					String postValue = FrameMapUtil.getString(postMap, e.getKey());
					if (postValue == null || !value.toString().equals(postValue)) {
						// 值不一致
						status = 40;
						statusMsg = "返回值不一致";
						resultComparison += e.getKey() + "的响应值" + postValue + "!=" + value.toString() + ";";
					}
				} else if (value instanceof Map) {
					@SuppressWarnings("unchecked")
					Map<String, Object> postCldMap = FrameMapUtil.getMap(postMap, e.getKey());
					@SuppressWarnings("unchecked")
					Map<String, Object> valueMap = FrameMapUtil.getMap(resultMap, e.getKey());
					// 获取正确的值
					if (valueMap != null) {
						Iterator<Entry<String, Object>> cldEntryKeyIterator = valueMap.entrySet().iterator();
						while (cldEntryKeyIterator.hasNext()) {
							Entry<String, Object> cld = cldEntryKeyIterator.next();
							String postCldValue = FrameMapUtil.getString(postCldMap, cld.getKey());
							Object cldValue = cld.getValue();
							if (cldValue instanceof String) {
								if (!cldValue.toString().equals(postCldValue)) {
									status = 40;
									statusMsg = "返回值不一致";
									resultComparison += e.getKey() + "." + cld.getKey() + "的响应值" + postCldValue + "!=" + cldValue.toString() + ";";
								}
							}
						}
					} else {
						status = 40;
						statusMsg = "返回值不一致";
						resultComparison += e.getKey() + "的响应值为null;";
					}
				}
			}
		}
		AppApiTestLog appApiTestLog = new AppApiTestLog();
		// 批次[测试时间]
		appApiTestLog.setBatchNo(batchNo);
		appApiTestLog.setAatdId(test.getAatdId());
		appApiTestLog.setTestUserId(user.getUserId());
		appApiTestLog.setParams(FrameJsonUtil.toString(params));
		// 响应结果
		appApiTestLog.setResult(resultPost);
		// 正确结果
		appApiTestLog.setResultSucc(test.getSuccResult());
		// 状态[30成功、40失败]
		appApiTestLog.setStatus(status);
		// 状态消息
		appApiTestLog.setStatusMsg(statusMsg);
		// 对比结果
		appApiTestLog.setResultComparison(resultComparison);
		appApiTestLogService.save(appApiTestLog);
		frame.setSucc();
		return frame;
	}

	private static String post(PrjApi pa, String url, Map<String, Object> params) {
		try {
			String contentType = MediaType.APPLICATION_FORM_URLENCODED_VALUE;
			Map<String, Object> methodMap = FrameJsonUtil.toMap(pa.getMethod());
			if (methodMap != null) {
				contentType = FrameMapUtil.getString(methodMap, "parameterContentType");
			}
			String result = null;
			if (MediaType.APPLICATION_FORM_URLENCODED_VALUE.equals(contentType)) {
				result = FrameHttpUtil.post(url, params);
			} else if (MediaType.APPLICATION_JSON_VALUE.equals(contentType)) {
				result = FrameHttpUtil.post(url, FrameJsonUtil.toString(params));
			} else {
				result = FrameHttpUtil.post(url, params);
			}
			return result;
		} catch (Exception e) {
			LOGGER.error("调用接口异常: " + e.getMessage(), e);
		}
		return null;
	}
}
